<template>
    <div class="upload-oss-file">
        <div class="img-video-wrapper">
            <draggable class="drag" animation="500" v-model="fileList" :move="onMove">
                <div class="content" v-for="(item, index) in fileList" :key="item.id">
                    <div class="image-wrapper" v-if="item.type == 1">
                        <el-image ref="elImage" :src="item.url" fit="cover" :preview-src-list="fileUrlList"></el-image>
                        <div class="operate">
                            <div class="operate-item" v-if="(!item.mainFlag && showSetMain || !item.showFlag && showFlag) && isSelect" :title="showFlag?'选中显示':'选为主图'" @click="selectMain(index)">
                                <i class="el-icon-check"></i>
                            </div>
                            <div class="operate-item" v-if="item.showFlag && showFlag" title="取消显示" @click="selectMain(index)">
                                <i class="el-icon-close"></i>
                            </div>
                            <div title="预览" class="operate-item" @click="handlePreviewImg(index)">
                                <i class="el-icon-zoom-in"></i>
                            </div>
                            <div title="删除" class="operate-item" @click="delFile(index)">
                                <i class="el-icon-delete"></i>
                            </div>
                        </div>
                        <div v-show="(item.mainFlag && showSetMain || item.showFlag && showFlag) && isSelect" class="check-wrapper">
                            <i class="el-icon-check"></i>
                        </div>
                    </div>
                    <div class="video-wrapper" v-else="item.type == 2">
                        <video :ref="'video' + index" controls width="100%" height="100%" :src="item.url">
                            <h2>我们很抱歉，您的浏览器<strong>不支持video标签</strong></h2>
                            <a href="https://www.google.cn/chrome/">点击这里下载浏览器</a>
                        </video>
                        <div class="operate">
                            <div title="删除" class="operate-item" @click="delFile(index)">
                                <i class="el-icon-delete"></i>
                            </div>
                        </div>
                    </div>
                    <!-- <div class="checkbox-wrapper" v-show="show">
                        <el-checkbox :label="item">""</el-checkbox>
                    </div> -->
                </div>
                <el-upload v-if="limitNum" class="upload-oss" drag action="#" :auto-upload="false" :accept="acceptFile"
                ref="fileUpload" :on-exceed="fnUploadExceed" :on-change="fnUploadChange" :http-request="fnUploadRequest"
                :limit="limitNum" :before-upload="beforeUpload" multiple :show-file-list="false">
                <i slot="default" class="el-icon-plus"></i>
            </el-upload>
            </draggable>
       
        </div>
        <!-- <div class="footer" v-show="show">
            <el-button type="primary">
                确认上传
            </el-button>
        </div> -->
    </div>
</template>

<script>
import * as Constants from "@/constants/constants";
import ComponentApi from "@/api/components/component";
import draggable from "vuedraggable"
import { nanoid } from "nanoid"
export default {
    components: {
        draggable,
    },
    props: {
        fileType: {
            type: String,
            default: "image,video"
        },
        limit: {
            type: Number,
            default: 5
        },
        limitSelect:{
            type:Number,
            default:3,
        },
        // 传过来的列表
        list: {
            type: Array,
        },
        folder: {
            type: String,
            default: 'img-video'
        },
        showSetMain:{
            type:Boolean,
            default:true,
        },
        showFlag:{
            type:Boolean,
            default:false,
        },
        mark:{
            type:Object,
            default: function (){
              return null;
            },
        },
        isSelect:{
            type:Boolean,
            default:true,
        },
    },
    watch: {
        // 重新赋值到fileList上面，顺便添加一个id
        list:{
            handler(val) {
                if(val){
                    // 这一段会避免死循环
                    if(val.length==this.fileList.length&&val.every((item,index)=>item.url==this.fileList[index].url)){
                        return
                    }
                }
                let arr = val.map(item => {
                    return { ...item, id: nanoid() }
                })
                if (this.showSetMain&&!arr.some(item=>item.mainFlag) && arr.length) {
                    let temp = arr.find(item => item.type == 1)
                    if (temp) {
                        temp.mainFlag = 1
                    }
                }
                this.fileList = arr
            },
            immediate:true
        },
        fileList(val) {
            this.toChildVal()
        },
    },
    computed: {
        limitNum() {
            return this.limit - this.fileList.length
        },
        fileUrlList() {
            return this.fileList.filter(item => item.type == 1).map(item => item.url)
        },
        acceptFile() {
            let acceptFile = ""
            if (this.fileType.includes("image")) {
                acceptFile = this.imgFile
            }
            if (this.fileType.includes("video")) {
                acceptFile = acceptFile + this.videoFile
            }
            return acceptFile
        },
    },
    data() {
        return {
            startUploadNum: 0,
            endUploadNum: 0,
            ossClient: null,
            imgFile: ".png,.jpg,.jpeg,.bmp,.png",
            videoFile: ",.mp4,.m2v,.mkv",
            fileList: [
            ],//已经上传的文件列表
        }
    },
    mounted() {
        ComponentApi.uploadOss().then(async res => {
            this.ossClient = (await import('ali-oss')).default({
                region: Constants.OSS_REGION,
                accessKeyId: res.data.accessKeyId,
                accessKeySecret: res.data.accessKeySecret,
                stsToken: res.data.securityToken,
                bucket: Constants.OSS_BUCKET
            })
        })

    },
    methods: {
        fnUploadChange(file) {
            if (file.status == 'ready') {
                this.startUploadNum = this.startUploadNum + 1
                this.$refs.fileUpload.submit()
                this.$refs.fileUpload.clearFiles()
            }
        },
        fnUploadExceed() {
            this.$message.error("你最多还可以上传" + this.limitNum + "张图片或视频")
        },
        beforeUpload(val) {
            if (val.size / 1024 / 1024 > 20) {
                this.$message.error("图片大小不能超过20MB")
                return false
            } else {
                return
            }
        },
        async fnUploadRequest(option) {
            // 清空已经上传的文件列表
            try {
                const _this = this
                // 判断已经上传过的不处理--情景：先上传成功3个，后补充1个，之前3个会循环调用。
                if (option && option.response && option.response.url) {
                    return
                }
                // 当前上传的文件
                let file = option.file
                const fileName = file.name
                const fileType = fileName.split("\.")[1];
                const newName = _this.$Utils.mathRand19() + "." + fileType;
                const storeAs = Constants.OSS_WEB_URL + _this.folder + '/' + newName;
                // TODO 测试 注释上传动作
                _this.ossClient.put(storeAs, file, {}).then(
                    function (ret) {
                        if (ret.res.statusCode === 200) {
                            let realUrl = ret.url.replace(Constants.OSS_URL, Constants.OSS_REAL_URL);
                            ret.url = realUrl;
                            _this.getFileList(realUrl, fileType)
                            // if (_this.uploadFileList.length == _this.uploadFileNum) {
                            //     _this.$emit("getImgVideo", [..._this.uploadFileList])
                            //     _this.uploadFileList = []
                            //     _this.uploadFileNum = 0
                            //     _this.$Utils.notifySuccess("上传成功")
                            // }
                            option.response = ret
                            return ret
                        } else {
                            option.onError('上传失败')
                        }
                    }
                ).catch(function (err) {
                    console.error(err)
                })
            } catch (error) {
                option.onError('上传失败')
                this.$error(error.message)
            }
        },
        getFileList(url, fileType) {
            this.fileList.push({
                id: nanoid(),
                url,
                type: this.imgFile.includes(fileType) ? 1 : 2,
            })

            if (!this.fileList.some(item => item.mainFlag)&&this.showSetMain) {
                let temp = this.fileList.find(item => item.type == 1)
                if (temp) {
                    temp.mainFlag = 1
                }
            }
            this.endUploadNum++
            if (this.endUploadNum == this.startUploadNum) {
                this.startUploadNum = 0
                this.endUploadNum = 0
                this.$Utils.notifySuccess("上传成功")
            }
        },
        selectMain(i) {
            this.fileList.forEach((item, index) => {
                if (item.type == 1&&this.showSetMain) {
                    if (index == i) {
                        this.$set(item, 'mainFlag', 1)
                    } else {
                        this.$set(item, 'mainFlag', 0)
                    }
                }else if(this.showFlag&&index == i){
                    if(item.showFlag){
                        this.$set(item, 'showFlag', 0)
                    }else{
                        if(this.fileList.filter(item=>item.showFlag).length==this.limitSelect){
                            return this.$message.error("最多只可以选中"+this.limitSelect+"张")
                        }
                        this.$set(item, 'showFlag', 1)
                    }
                }
            })
            this.toChildVal()
        },
        delFile(index) {
            this.fileList.splice(index, 1)
            if (!this.fileList.some(item => item.mainFlag)&&this.showSetMain) {
                let temp = this.fileList.find(item => item.type == 1)
                if (temp) {
                    temp.mainFlag = 1
                }
            }
        },
        toChildVal() {
            if (this.endUploadNum == this.startUploadNum) {
                let arr = this.fileList.map((item, index) => {


                    let obj = Object.assign({ ...item }, { sort: index + 1})

                    if(this.showSetMain){
                        obj.mainFlag = item.mainFlag ? 1 : 0
                    }else if(this.showFlag){
                        obj.showFlag = item.showFlag ? 1 : 0
                    }
                    delete obj.id
                    return obj
                })
                if(this.mark){
                    this.$emit("getImgVideo", {list:arr,mark:this.mark})
                }else{
                    this.$emit("getImgVideo", arr)
                }

            }
        },
        handlePreviewImg(index) {
            index = index - this.fileList.slice(0, index).filter(item => item.type == 2).length
            this.$refs.elImage[index].showViewer = true
            this.$nextTick(() => {
                this.addHideToMask(this.$refs.elImage[index])
            })
        },
        onMove(e, b) {
            // 这个函数是推拽之前执行的
            //false表示阻止拖拽
            return true;
        },

        // 给每一个预览图片的遮罩层都添加一个点击事件，点击阴影可以取消
        addHideToMask(el) {
            const mask = el.$el.querySelector('.el-image-viewer__mask')
            if (mask) {
                let hide = () => {
                    el.showViewer = false
                }
                // 遮罩层增加点击事件，关闭预览
                mask.addEventListener('click', hide)
                // hook卸载事件，移除之前添加在mask元素的事件
                this.$once('hook:beforeMount', () => {
                    mask && mask.removeEventListener('click', hide)
                })
            }
        },
        // 上传到公共图片
        handleUploadLibrary() {

        }
    },

}
</script>

<style lang="scss" scoped>
@mixin operate {
    &:hover {
        .operate {
            display: flex !important;
            align-items: center;
            flex-wrap: wrap;
        }
    }

    .operate {
        display: none;
        position: absolute;
        // background: ;
        width: 180px;
        height: 180px;
        top: 0;
        left: 0;
        background-color: rgba(0, 0, 0, .5);

        .operate-item {
            line-height: 60px;
            text-align: center;
            font-size: 28px;
            color: white;
            cursor: pointer;
            width: 100%;
            flex-shrink: 0;

            &:hover {
                background-color: rgba(0, 0, 0, .7);
            }
        }

    }
}

.footer {
    margin: 10px 0 20px 0;
}

.img-video-wrapper {
    display: flex;
    margin: 10px 0;

    .drag {
        display: flex;
        flex-wrap: wrap;
        .content {

            position: relative;
            margin-bottom:7px;
            .image-wrapper {
                position: relative;
                margin-right: 20px;



                .el-image {
                    width: 180px;
                    height: 180px;
                    // margin-right: 20px;
                    vertical-align: bottom
                }

                @include operate;

                .check-wrapper {
                    position: absolute !important;
                    bottom: 0;
                    right: 0;
                    font-size: 30px;
                    color: white;
                    font-weight: 900;
                    border: 20px solid #07C160;
                    width: 0;
                    height: 0;
                    border-top: 20px solid transparent;
                    border-left: 20px solid transparent;

                    .el-icon-check {

                        position: relative;
                        bottom: 11px;
                        right: 7px;
                    }
                }
            }

            .video-wrapper {
                width: 180px;
                height: 180px;
                display: flex;
                align-items: center;
                position: relative;
                margin-right: 20px;
                @include operate;

                .operate {
                    height: 60px;
                }
            }

            .checkbox-wrapper {
                margin-top: 10px;
                text-align: center;

                .el-checkbox {
                    &::v-deep .el-checkbox__input {
                        .el-checkbox__inner {
                            width: 20px;
                            height: 20px;

                            &::after {
                                height: 11px;
                                left: 7px;
                                top: 2px;
                            }
                        }

                    }

                    &::v-deep .el-checkbox__label {
                        display: none;
                    }
                }
            }
        }
    }

    .upload-oss {
        &::v-deep .el-upload {
            .el-upload-dragger {
                width: 178px;
                height: 178px;
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 30px;
            }
        }
    }
}</style>
